﻿using System;
using System.Globalization;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Web.Mvc;

namespace Common.Extensions
{
    /// <summary>
    /// 针对枚举描述信息的扩展
    /// </summary>
    public static class EnumExtension
    {
        /// <summary>
        /// 获取枚举值的描述信息
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string Description(this Enum enumValue)
        {

            var field = enumValue.GetType().GetField(enumValue.ToString());
            if (field == null)
            {
                return string.Empty;
            }
            DescriptionAttribute descriptionAttribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;

            if (descriptionAttribute == null) return string.Empty;

            return descriptionAttribute.Description;
        }

        /// <summary>
        /// 获取枚举的所有值及描述
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static Dictionary<TKey, string> GetDescriptions<TKey>(this Type enumType)
        {
            if (!enumType.IsEnum) throw new ArgumentException("enumType");

            var dic = new Dictionary<TKey, string>();

            var values = Enum.GetValues(enumType);

            foreach (var value in values)
            {
                TKey itemKey = (TKey)value;

                string itemValue = Description((Enum)value);

                dic.Add(itemKey, itemValue);
            }

            return dic;
        }


        /// <summary>
        /// 根据枚举项获取值枚举值
        /// </summary>
        /// <param name="value"></param>
        public static int GetValue(this System.Enum obj)
        {
            return obj.GetHashCode();
        }

        /// <summary>
        ///根据字符串名称获取枚举值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static int GetValue<T>(this string obj)
        {
            return System.Enum.Parse(typeof(T), obj).GetHashCode();
        }

        /// <summary>
        /// 根据枚举项获取枚举名称
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string GetName<T>(this System.Enum obj)
        {
            return System.Enum.GetName(typeof(T), obj);
        }

        /// <summary>
        /// 根据值获取枚举名称
        /// </summary>
        /// <returns></returns>
        public static string GetName<T>(this System.Int32 value)
        {
            return System.Enum.GetName(typeof(T), value);
        }


        /// <summary>
        /// 根据名称转换为枚举
        /// </summary>
        /// <returns></returns>
        public static T EnumObj<T>(this string obj)
        {
            return (T)System.Enum.Parse(typeof(T), obj);
        }

        /// <summary>
        /// 根据值转换为枚举
        /// </summary>
        /// <returns></returns>
        public static T EnumObj<T>(this  System.Int32 value)
        {
            return (T)System.Enum.ToObject(typeof(T), value);
        }


        /// <summary>
        /// Enum To SelectList
        /// </summary>
        /// <typeparam name="T">Enum</typeparam>
        /// <param name="defaultText">默认显示标头</param>
        /// <param name="selectedValue">要选中选项值</param>
        /// <returns>SelectList</returns>
    
        public static SelectList ToSelectList<T>(string defaultText, object selectedValue = null) where T : struct, IConvertible
        {
            var itemList = new List<SelectListItem> { new SelectListItem { Text = defaultText, Value = "" } };
            if (!typeof(T).IsEnum) throw new ArgumentException("必须是枚举类型!");
            itemList.AddRange(from Object x in Enum.GetValues(typeof(T))
                              select new SelectListItem
                              {
                                  Value = ((int)x).ToString(CultureInfo.InvariantCulture),
                                  Text = Description((Enum)x)

                              });
            return new SelectList(itemList, "Value", "Text", selectedValue);
        }


        public static Dictionary<string, int> ToDictionary<T>()
        {
            var dic = new Dictionary<string, int>();
            foreach (var item in Enum.GetValues(typeof(T)))
            {
                dic.Add(item.ToString(), (int)item);
            }
            return dic;
        }


        public static List<SelectListItem> ToSelectListOthers<T>(object selectedValue = null) where T : struct, IConvertible
        {
            var itemList = new List<SelectListItem>();
            if (!typeof(T).IsEnum) throw new ArgumentException("必须是枚举类型!");
            itemList.AddRange(from Object x in Enum.GetValues(typeof(T))
                              select new SelectListItem
                              {
                                  Value = ((int)x).ToString(CultureInfo.InvariantCulture),
                                  Text = Description((Enum)x),
                                  Selected = (int)x == (int)selectedValue ? true : false,
                              });
            return itemList;
            // return new SelectList(itemList, "Value", "Text", selectedValue);
        }
    }
}